package model;

import java.io.Serializable;
import java.util.ArrayList;

public class Map implements Serializable {
  /**
	 * 
	 */
	private static final long serialVersionUID = 2466194864378679475L;
private Territory[][] board;
  
  public Map(Player Tester, Player Enemy, Player Ally) {// for Sijing's test
    board = new Territory[5][5];
    
    for(int i = 0; i < 5; i++) 
		  for(int j = 0; j < 5; j++) {
			  int k = i * 5 + j;
			  if ((k == 1) || (k == 7) || (k == 13) || (k == 19)) 
			    board[i][j] = new Territory(k, i + j, Ally, i, j);
			  else if ((i != j))
				board[i][j] = new Territory(k, i + j, Tester, i, j);
			  else 
				  board[i][j] = new Territory(k, i + j, Enemy, i, j);
		      board[i][j].getOwner().updateTerritory(board[i][j]);
		  }
      for (int i = 0; i < 5; i++)
    	  for (int j = 0; j < 5; j++){
    		  if (i - 1 >= 0) 
    			  board[i][j].addNeighbor(board[i - 1][j]);
    		  if (i + 1 < 5) 
    			  board[i][j].addNeighbor(board[i + 1][j]);
    		  if (j - 1 >= 0) 
    			  board[i][j].addNeighbor(board[i][j - 1]);
    		  if (j + 1 < 5) 
    			  board[i][j].addNeighbor(board[i][j + 1]);
    		  if ((i - 1 >= 0) && (j - 1 >= 0)) 
    			  board[i][j].addNeighbor(board[i - 1][j - 1]);
    		  if ((i + 1 < 5) && (j + 1 < 5)) 
    			  board[i][j].addNeighbor(board[i + 1][j + 1]);
    		  if ((i - 1 >= 0) && (j + 1 < 5)) 
    			  board[i][j].addNeighbor(board[i - 1][j + 1]);
    		  if ((i + 1 < 5) && (j - 1 >= 0)) 
    			  board[i][j].addNeighbor(board[i + 1][j - 1]);
   		  
    	  }
  }
  public Map(){// David write the constructor and implements the only map
	  
  }
    
  public void updateTerritory(Territory terr) {//david change this
    int row = terr.getLocation() / 5;
    int column = terr.getLocation() % 5;
    board[row][column].updateTerritory(terr);
    for (TechnologyLevel level : TechnologyLevel.values())
    	if (terr.getTroopAmount(level, terr.getOwner()) > 0)
    		if (level.CombatBonus() > terr.getOwner().getLevel().CombatBonus())
    			terr.getOwner().setLevel(level);
    
  }
  
  public Territory getTerritory (int location) {//for Sijing' test, David should rewrite another one
      return board[location / 5][location % 5];
  }
  
  /*
   * Trying to find a path between two territories under the same owner
   */
 /* public boolean FindPath(Territory s, Territory d) {
	  if(!(s.getOwner().equals(d.getOwner()))) {
		  return (Math.abs(s.GetX() - d.GetX()) < 2 && Math.abs(s.GetX() - d.GetX()) < 2);
	  } else
		  return (routeProcess(s.GetX()+1,s.GetY(),d) || routeProcess(s.GetX()-1,s.GetY(),d) 
				  || routeProcess(s.GetX(),s.GetY()+1,d) || routeProcess(s.GetX(),s.GetY()-1,d));
	  //Needs to be re-implemented (its kinda sloppy)
  }*/
  
  public boolean routeProcess(Territory s, Territory d) {
	  ArrayList<Territory> visited = new ArrayList<Territory>();
	  visited.add(s);
	  int k = 0;
	  while (!visited.isEmpty()){
	    if (visited.contains(d))
	    	return true;
		if (k >= visited.size())
			break;
	    Territory curr = visited.get(k);
		k++;
	    for (Territory neighbor: curr.getNeighbors()) 
			if (((neighbor.getOwner() == curr.getOwner()) || neighbor.getOwner().isAlly(curr.getOwner())) && (!visited.contains(neighbor))){
			  visited.add(neighbor);	
			}
	  }
	  return false;
  }
  
  public void setupMap(ArrayList<Territory> updates) {//David write this
  } 
 }